
package com.hlkj.pay.app.merchant.ext.impl.easypay;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import cn.hutool.json.JSONArray;
import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.framework.extension.annotation.Extension;
import com.hlkj.pay.app.common.IUploadService;
import com.hlkj.pay.app.merchant.ext.ChannelMerchantAccessExtPt;
import com.hlkj.pay.app.merchant.ext.MerchantExtConstant;
import com.hlkj.pay.app.merchant.ext.dto.access.*;
import com.hlkj.pay.app.merchant.ext.impl.easypay.dto.EasyPayConfig;
import com.hlkj.pay.app.merchant.ext.impl.easypay.dto.EasypayAppChannelParams;
import com.hlkj.pay.app.merchant.ext.impl.easypay.handler.EasyPayMerchantAccessConfigHandler;
import com.hlkj.pay.app.merchant.ext.impl.easypay.handler.EasyPayMerchantAccessInfoHandler;
import com.hlkj.pay.app.merchant.ext.impl.easypay.utils.EasyPayCallBackParamsParseUtil;
import com.hlkj.pay.app.merchant.ext.impl.easypay.utils.EasyPaySignUtil;
import com.hlkj.pay.dto.merchant.AccessChannelParamsDto;
import com.hlkj.pay.dto.merchant.MerchantAccessDto;
import com.hlkj.pay.enums.CommonEnum;
import com.hlkj.pay.enums.MerchantEnum;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAccessAuthDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAccessInfoDO;
import com.hlkj.pay.infrastructure.model.pay.ProviderChannelConfigDO;
import com.hlkj.pay.util.HttpRequestUtil;
import com.hlkj.pay.vo.order.resp.MerchantProductQueryResp;
import com.huifu.bspay.sdk.opps.core.request.V2MerchantBasicdataEntRequest;
import com.huifu.bspay.sdk.opps.core.request.V2MerchantBasicdataIndvRequest;
import com.huifu.bspay.sdk.opps.core.request.V2MerchantBusiOpenRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 汇付进件操作
 * 
 * @author HlpayTeam
 * @date 2024/09/26 10:25
 */
@Slf4j
@Repository
@RequiredArgsConstructor
@Extension(bizId = MerchantExtConstant.CHANNEL_EASY_PAY)
public class EasyPayMerchantAccessExtPt implements ChannelMerchantAccessExtPt {

    private final IUploadService uploadService;

    private final EasyPayMerchantAccessInfoHandler easyPayMerchantAccessInfoHandler;

    private final EasyPayMerchantAccessConfigHandler easyPayMerchantAccessConfigHandler;

    @Override
    public void channelConfigCheck(ChannelMerchantAccessCommonContext channelMerchantAccessCommonContext) {

    }
    @Override
    public void merchantAccess(ChannelMerchantAccessContext channelMerchantAccessContext) {
        log.info("易生渠道提交进件 请求参数:{}", JsonUtils.toJsonString(channelMerchantAccessContext));
        if (channelMerchantAccessContext.isProcessStatus()) {
            easyPayMerchantAccessInfoHandler.merchantAccess(channelMerchantAccessContext);
        }
    }

    @Override
    public String requestUrl(MerchantAccessDto merchantAccessInfoDO) {
        MerchantEnum.ACCESS_STATUS accessStatus = MerchantEnum.ACCESS_STATUS.from(merchantAccessInfoDO.getMerchantAccessInfo().getStatus());
        switch (accessStatus) {
            case WAIT_SETTING:
                return new V2MerchantBusiOpenRequest().getFunctionCode().getCode();
            default:
                switch (MerchantEnum.MERCHANT_TYPE.from(merchantAccessInfoDO.getMerchantAccessInfo().getType())) {
                    case PERSONAL:
                        return new V2MerchantBasicdataIndvRequest().getFunctionCode().getCode();
                    default:
                        return new V2MerchantBasicdataEntRequest().getFunctionCode().getCode();
                }
        }
    }

    @Override
    public String channelParams(AccessChannelParamsDto accessChannelParamsDto) {
        EasypayAppChannelParams easypayAppChannelParams = new EasypayAppChannelParams();
        easypayAppChannelParams.setCustomerNo(accessChannelParamsDto.getSubMchId());
        if (StringUtils.hasText(accessChannelParamsDto.getExtendA())) {
            JSONArray arr = JsonUtils.parseArray(accessChannelParamsDto.getExtendA());
            easypayAppChannelParams.setTerminalId(arr.getJSONObject(0).getStr("termCode"));
        }
        return JsonUtils.toJsonStringNotNull(easypayAppChannelParams);
    }

    @Override
    public void merchantAccessQuery(ChannelMerchantAccessQueryContext channelMerchantAccessQueryContext) {
        MerchantAccessInfoDO merchantAccessInfoDO = channelMerchantAccessQueryContext.getMerchantAccessInfo();
        if (!StringUtils.hasText(merchantAccessInfoDO.getApplyNo()) && !StringUtils.hasText(merchantAccessInfoDO.getSubMchId())) {
            channelMerchantAccessQueryContext.setProcessStatus(Boolean.FALSE);
            channelMerchantAccessQueryContext.setRemark("申请单号和商户号不能都为空");
            return;
        }
        easyPayMerchantAccessInfoHandler.accessQueryRequest(channelMerchantAccessQueryContext);
    }

    @Override
    public void merchantSign(ChannelMerchantAccessSignContext channelMerchantAccessSignContext) {
        // 易生的业务开通就是电子协议生成 和签署电子协议
        easyPayMerchantAccessInfoHandler.processElecContract(channelMerchantAccessSignContext);
//        channelMerchantAccessSignContext.setAccessStatus(MerchantEnum.ACCESS_STATUS.WAIT_SET);
    }

    @Override
    public void merchantSignQuery(ChannelMerchantAccessSignContext channelMerchantAccessSignContext) {
        easyPayMerchantAccessInfoHandler.accessQueryRequest(channelMerchantAccessSignContext);
    }

    @Override
    public void merchantBusinessOpen(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
        MerchantAccessInfoDO merchantAccessInfo = channelMerchantBusinessContext.getMerchantAccessDto().getMerchantAccessInfo();
        MerchantEnum.CHANNEL_CONFIG_STATUS accessStatus = MerchantEnum.CHANNEL_CONFIG_STATUS.from(merchantAccessInfo.getAuditStatus());
        switch (accessStatus) {
            case SUBMERINFO:
//                easyPayMerchantAccessInfoHandler
                easyPayMerchantAccessConfigHandler.processSubMerInfoQuery(channelMerchantBusinessContext);
                break;
            case SIGN:
//                 easyPayMerchantAccessInfoHandler.processElecContract(channelMerchantBusinessContext);
                break;
            case SUBMIT:
//                channelMerchantBusinessContext.setAccessStatus(MerchantEnum.ACCESS_STATUS.WAIT_SET);
//                channelMerchantBusinessContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.SUBMIT);
                easyPayMerchantAccessInfoHandler.accessQueryRequest(channelMerchantBusinessContext);
                break;
            case AUDITING:
                // 审核中
                ChannelMerchantAccessQueryContext channelMerchantAccessQueryContext = new ChannelMerchantAccessQueryContext();
                channelMerchantAccessQueryContext.setMerchantAccessInfo(channelMerchantBusinessContext.getMerchantAccessDto().getMerchantAccessInfo());
                channelMerchantAccessQueryContext.setProviderChannelConfig(channelMerchantBusinessContext.getProviderChannelConfig());
                easyPayMerchantAccessInfoHandler.accessQueryRequest(channelMerchantAccessQueryContext);
                if (channelMerchantBusinessContext.isProcessStatus()) {
                    channelMerchantBusinessContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.WECHAT_CONFIG);
                    channelMerchantBusinessContext.setAccessStatus(MerchantEnum.ACCESS_STATUS.APPROVE_SUCCESS);
                }
        }

    }

    @Override
    public void wechatConfigInit(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
        easyPayMerchantAccessConfigHandler.wechatConfigInit(channelMerchantBusinessContext);
        channelMerchantBusinessContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.WECHAT_AUTH);
    }

    @Override
    public void wechatConfigAdd(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
        // 获取子商户信息进行微信参数配置
        easyPayMerchantAccessConfigHandler.processWxAuth(channelMerchantBusinessContext);
    }

    @Override
    public void wechatConfigQuery(ChannelMerchantAccessAuthQueryContext channelMerchantAccessAuthQueryContext) {
        // 文件上传完成就是微信参数自动配置
        easyPayMerchantAccessConfigHandler.processWxConfigQuery(channelMerchantAccessAuthQueryContext);
    }

    @Override
    public void wechatAuthConfig(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
        // 易生 为自动认证无需处理
        channelMerchantBusinessContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.FINISH);
    }

    @Override
    public boolean authConfigQueryType() {
        return true;
    }

    @Override
    public void wechatAuthQuery(ChannelMerchantAccessAuthQueryContext channelMerchantAccessAuthQueryContext) {
        easyPayMerchantAccessConfigHandler.processWxAuthQuery(channelMerchantAccessAuthQueryContext);
        List<MerchantAccessAuthDO> merchantAccessAuthList = channelMerchantAccessAuthQueryContext.getMerchantAccessAuthDbList();
        MerchantAccessInfoDO merchantAccessInfo = channelMerchantAccessAuthQueryContext.getMerchantAccessInfo();
        if (!CollectionUtils.isEmpty(merchantAccessAuthList)) {
            merchantAccessAuthList.stream().forEach(merchantAccessAuthDO -> {
                merchantAccessAuthDO.setType(1);
                merchantAccessAuthDO.setSn(merchantAccessInfo.getSn());
                merchantAccessAuthDO.setAccessId(merchantAccessInfo.getId());
                if (merchantAccessAuthDO.getQrCodeArray() != null && merchantAccessAuthDO.getQrCodeArray().length > 0) {
                    CommonResult<String> commonResult = uploadService.upload(merchantAccessAuthDO.getQrCodeArray(), CommonEnum.OssEnum.IMAGE);
                    merchantAccessAuthDO.setAuthUrl(commonResult.getData());
                }
            });
        }
        channelMerchantAccessAuthQueryContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.ALIPAY_AUTH);
    }

    @Override
    public void alipayAuthConfig(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
//        easyPayMerchantAccessConfigHandler.processAliAuth(channelMerchantBusinessContext);
        // 支付宝参数配置
        // 易生 为自动认证无需处理
        channelMerchantBusinessContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.ALIPAY_AUTHING);
    }

    @Override
    public void alipayAuthQuery(ChannelMerchantAccessAuthQueryContext channelMerchantAccessAuthQueryContext) {
        easyPayMerchantAccessConfigHandler.processAliAuthQuery(channelMerchantAccessAuthQueryContext);
        List<MerchantAccessAuthDO> merchantAccessAuthList = channelMerchantAccessAuthQueryContext.getMerchantAccessAuthDbList();
        MerchantAccessInfoDO merchantAccessInfo = channelMerchantAccessAuthQueryContext.getMerchantAccessInfo();
        if (!CollectionUtils.isEmpty(merchantAccessAuthList)) {
            merchantAccessAuthList.stream().forEach(merchantAccessAuthDO -> {
                merchantAccessAuthDO.setType(2);
                merchantAccessAuthDO.setSn(merchantAccessInfo.getSn());
                merchantAccessAuthDO.setAccessId(merchantAccessInfo.getId());
            });
        }
        channelMerchantAccessAuthQueryContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.FINISH);
    }

    @Override
    public MerchantAccessCallBackDto accessCallBackParamsParse(HttpServletRequest request, ProviderChannelConfigDO providerChannelConfigDO) {
        String accessCallBody = HttpRequestUtil.requestBodyParams(request);
        return this.accessCallBackParamsParse(accessCallBody, providerChannelConfigDO);
    }

    @Override
    public CommonResult<String> accessCallbackParse(String callBackBody, List<ProviderChannelConfigDO> channelConfigDOList) {
        return null;
    }

    public MerchantAccessCallBackDto accessCallBackParamsParse(String callBackBody, ProviderChannelConfigDO providerChannelConfigDO) {
        String channelConfig = providerChannelConfigDO.getParamsConfig();
        // 配置转换
        EasyPayConfig easyPayConfig = JsonUtils.parseObject(channelConfig, EasyPayConfig.class);
        return EasyPayCallBackParamsParseUtil.accessCallBackParamsParse(callBackBody, easyPayConfig);
    }

    @Override
    public MerchantBusinessCallBackDto businessCallBackParamsParse(String callBackBody, ProviderChannelConfigDO providerChannelConfigDO) {
        String channelConfig = providerChannelConfigDO.getParamsConfig();
        // 配置转换
        EasyPayConfig easyPayConfig = JsonUtils.parseObject(channelConfig, EasyPayConfig.class);
        return EasyPayCallBackParamsParseUtil.businessCallBackParamsParse(callBackBody, easyPayConfig);
    }

    @Override
    public boolean verify(String callBackBody, ProviderChannelConfigDO providerChannelConfigDO) {
        String channelConfig = providerChannelConfigDO.getParamsConfig();
        // 配置转换
        EasyPayConfig easyPayConfig = JsonUtils.parseObject(channelConfig, EasyPayConfig.class);
        return EasyPayCallBackParamsParseUtil.verify(easyPayConfig, callBackBody);
    }

    @Override
    public String callBackResponse(CommonResult commonResult) {
        //返回内容需要传机构号，暂取不到，需要修改整体逻辑
        ProviderChannelConfigDO providerChannelConfigDO = (ProviderChannelConfigDO) commonResult.getData();
        EasyPayConfig easyPayConfig = JsonUtils.parseObject(providerChannelConfigDO.getParamsConfig(), EasyPayConfig.class);
        Map<String, String> retObj = new HashMap<>();
        retObj.put("version", "1.0");
        retObj.put("clientCode", easyPayConfig.getOrgCode());
        if (commonResult.isSuccess()) {
            retObj.put("retCode", "0000");
            retObj.put("retMsg", "success");
        }
        else {
            retObj.put("retCode", "9999");
            retObj.put("retMsg", "error");
        }
        retObj.put("MAC", EasyPaySignUtil.md5Sign(retObj, easyPayConfig.getMd5Key()));
        return retObj.toString();
    }

    @Override
    public void termAdd(ChannelMerchantTermContext channelMerchantTermContext) {

    }

    @Override
    public void reloadMerchantAuth(ChannelMerchantBusinessContext channelMerchantBusinessContext) {

    }

    @Override
    public void channelSplit(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
        // 拆分
        easyPayMerchantAccessConfigHandler.channelSplit(channelMerchantBusinessContext);
    }

    @Override
    public void productUpdate(ChannelMerchantBusinessContext channelMerchantBusinessContext) {

    }

    @Override
    public Integer queryMerAuthStatus(ChannelMerchantAccessAuthQueryContext channelMerchantAccessAuthQueryContext) {
        return null;
    }

    @Override
    public MerchantProductQueryResp productQuery(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
        return null;
    }

    @Override
    public MerchantChannelSplitCallBackDto easySplitCallBackParamsParse(HttpServletRequest request, ProviderChannelConfigDO providerChannelConfigDO) {
        String callBackBody = HttpRequestUtil.requestBodyParams(request);
        log.info("易生拆分回调结果: {}", callBackBody);
        String channelConfig = providerChannelConfigDO.getParamsConfig();
        // 配置转换
        EasyPayConfig easyPayConfig = JsonUtils.parseObject(channelConfig, EasyPayConfig.class);
        return EasyPayCallBackParamsParseUtil.easySplitCallBackParamsParse(callBackBody, easyPayConfig);
    }

}
